using Microsoft.SqlServer.Management.Sdk.Sfc;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Globalization;

namespace Microsoft.SqlServer.Management.SqlManagerUI.Scripting
{
	internal class ScriptObjectContainer : ScriptContainer
	{
		private IEnumerable dataScript;

		private IEnumerable dropDataScript;

		private string[] bindRuleScript = new string[0];

		private List<string> dropScript = new List<string>();

		private string[] createScript = new string[0];

		private List<string> permissionScript = new List<string>();

		private string[] headerScript = new string[0];

		private string[] enableDdLTriggerScript = new string[0];

		private string[] disableDdLTriggerScript = new string[0];

		private Microsoft.SqlServer.Management.SqlManagerUI.ObjectInfo objectInfo;

		private ScriptActions _action;

		private Urn urn;

		public override string Key
		{
			get
			{
				return this.urn;
			}
		}

		public override Microsoft.SqlServer.Management.SqlManagerUI.ObjectInfo ObjectInfo
		{
			get
			{
				return this.objectInfo;
			}
		}

		protected virtual bool ContainsScriptItems
		{
			get
			{
				bool flag = false;
				if (this.dataScript != null && this.dataScript is TableDataWrapper)
				{
					TableDataWrapper tableDataWrapper = (TableDataWrapper)this.dataScript;
					if (tableDataWrapper.HasWritableColumns)
					{
						flag = true;
					}
				}
				return this.dropScript.Count > 0 || this.permissionScript.Count > 0 || this.createScript.Length > 0 || this.bindRuleScript.Length > 0 || this.disableDdLTriggerScript.Length > 0 || this.enableDdLTriggerScript.Length > 0 || this.dropDataScript != null || flag;
			}
		}

		public ScriptObjectContainer(Microsoft.SqlServer.Management.SqlManagerUI.ObjectInfo objectInfo)
		{
			if (objectInfo == null)
			{
				throw new ArgumentNullException("ObjectInfo");
			}
			this.urn = objectInfo.Urn;
			this.objectInfo = objectInfo;
		}

		public override void AddFragment(Microsoft.SqlServer.Management.SqlManagerUI.ObjectInfo objectInfo, IEnumerable script, ScriptActions action)
		{
			if (objectInfo == null)
			{
				throw new ArgumentNullException("source");
			}
			if (script == null)
			{
				throw new ArgumentNullException("script");
			}
			this.ValidateSource(objectInfo.Urn);
			if (action <= ScriptActions.DropData)
			{
				switch (action)
				{
				case ScriptActions.Permission:
					this.AddPermissionScript(script);
					this._action = action;
					return;
				case ScriptActions.Create:
					this.AddCreateScript(script);
					this._action = action;
					return;
				case ScriptActions.Permission | ScriptActions.Create:
					break;
				case ScriptActions.Drop:
					this.AddDropScript(script);
					this._action = action;
					return;
				default:
					if (action == ScriptActions.Header)
					{
						this.AddHeaderScript(script);
						return;
					}
					if (action == ScriptActions.DropData)
					{
						this.AddDropDataScript(script);
						return;
					}
					break;
				}
			}
			else if (action <= ScriptActions.Bindings)
			{
				if (action != ScriptActions.Data)
				{
					if (action == ScriptActions.Bindings)
					{
						this.AddBindRuleScript(script);
						return;
					}
				}
				else
				{
					this.AddDataScript(script);
					if (this._action != ScriptActions.Create && this._action != ScriptActions.Drop)
					{
						this._action = action;
						return;
					}
					return;
				}
			}
			else
			{
				if (action == ScriptActions.DisableDDLTrigger)
				{
					this.AddDisableDdlTriggerScript(script);
					return;
				}
				if (action == ScriptActions.EnableDDLTrigger)
				{
					this.AddEnableDdlTriggerScript(script);
					return;
				}
			}
			throw new InvalidOperationException();
		}

		private void AddEnableDdlTriggerScript(IEnumerable script)
		{
			this.enableDdLTriggerScript = ScriptObjectContainer.GetStringArray(script);
		}

		private void AddDisableDdlTriggerScript(IEnumerable script)
		{
			this.disableDdLTriggerScript = ScriptObjectContainer.GetStringArray(script);
		}

		public override void Script(ScriptWriter scriptWriter)
		{
			if (scriptWriter == null)
			{
				throw new ArgumentNullException("scriptWriter");
			}
			if (!this.ContainsScriptItems)
			{
				return;
			}
			scriptWriter.InitializeWriterForUrn(this.objectInfo, this._action);
			try
			{
				this.AppendHeaderScript(scriptWriter);
				this.AppendDisableDDLTriggerScript(scriptWriter);
				this.AppendDropScript(scriptWriter);
				this.AppendCreateScript(scriptWriter);
				this.AppendDropDataScript(scriptWriter);
				this.AppendDataScript(scriptWriter);
				this.AppendRuleBindingScript(scriptWriter);
				this.AppendPermissionScript(scriptWriter);
				this.AppendEnableDdlTriggerScript(scriptWriter);
			}
			catch (Exception)
			{
				throw;
			}
			finally
			{
				scriptWriter.CloseWriterForUrn();
			}
		}

		private void AppendEnableDdlTriggerScript(ScriptWriter scriptWriter)
		{
			this.AppendScriptFragment(scriptWriter, this.enableDdLTriggerScript);
		}

		private void AppendDisableDDLTriggerScript(ScriptWriter scriptWriter)
		{
			this.AppendScriptFragment(scriptWriter, this.disableDdLTriggerScript);
		}

		private void AppendDropDataScript(ScriptWriter scriptWriter)
		{
			if (this.dropDataScript != null)
			{
				this.AppendScriptFragment(scriptWriter, this.dropDataScript);
			}
		}

		private void AppendRuleBindingScript(ScriptWriter scriptWriter)
		{
			this.AppendScriptFragment(scriptWriter, this.bindRuleScript);
		}

		protected virtual void AppendHeaderScript(ScriptWriter scriptWriter)
		{
			this.AppendScriptComment(scriptWriter, this.headerScript);
		}

		protected virtual void AppendCreateScript(ScriptWriter scriptWriter)
		{
			this.AppendScriptFragment(scriptWriter, this.createScript);
		}

		protected virtual void AppendDropScript(ScriptWriter scriptWriter)
		{
			this.AppendScriptFragment(scriptWriter, this.dropScript);
		}

		protected virtual void AppendPermissionScript(ScriptWriter scriptWriter)
		{
			this.AppendScriptFragment(scriptWriter, this.permissionScript);
		}

		protected void AppendScriptFragment(ScriptWriter scriptWriter, IEnumerable fragment)
		{
			foreach (string text in fragment)
			{
				string text2 = text.Trim();
				if (text2.Length != 0)
				{
					scriptWriter.Write(text2);
				}
			}
		}

		protected void AppendDataScriptFragment(ScriptWriter scriptWriter, IEnumerable fragment)
		{
			if (scriptWriter.IsWritingObjectOfTypeSupported(fragment))
			{
				scriptWriter.WriteObject(fragment);
				return;
			}
			ScriptObjectContainer.AppendDataScriptAsInsertStatements(scriptWriter, fragment);
		}

		private static void AppendDataScriptAsInsertStatements(ScriptWriter scriptWriter, IEnumerable fragment)
		{
			int num = 0;
			int num2 = 0;
			foreach (string text in fragment)
			{
				string text2 = text.Trim();
				if (text2.Length != 0)
				{
					if (num >= 100)
					{
						num = 0;
						num2++;
						scriptWriter.Write(text2, true);
						scriptWriter.WriteComment(string.Format(CultureInfo.InvariantCulture, "print 'Processed {0} total records'", new object[]
						{
							num2 * 100
						}));
					}
					else
					{
						scriptWriter.Write(text2, false);
						num++;
					}
				}
			}
		}

		protected void AppendScriptComment(ScriptWriter writer, IEnumerable comment)
		{
			foreach (string text in comment)
			{
				string text2 = text.Trim();
				if (text2.Length != 0)
				{
					writer.WriteComment(text2);
				}
			}
		}

		private void AppendDataScript(ScriptWriter scriptWriter)
		{
			if (this.dataScript != null)
			{
				this.AppendDataScriptFragment(scriptWriter, this.dataScript);
			}
		}

		private void AddHeaderScript(IEnumerable script)
		{
			if (this.headerScript.Length != 0)
			{
				throw new InvalidOperationException();
			}
			this.headerScript = ScriptObjectContainer.GetStringArray(script);
		}

		private void AddCreateScript(IEnumerable script)
		{
			if (this.createScript.Length != 0)
			{
				throw new InvalidOperationException();
			}
			this.createScript = ScriptObjectContainer.GetStringArray(script);
		}

		private void AddDropScript(IEnumerable script)
		{
			this.dropScript.AddRange(ScriptObjectContainer.GetStringArray(script));
		}

		private void AddBindRuleScript(IEnumerable script)
		{
			if (this.bindRuleScript.Length != 0)
			{
				throw new InvalidOperationException();
			}
			this.bindRuleScript = ScriptObjectContainer.GetStringArray(script);
		}

		private void AddDataScript(IEnumerable script)
		{
			this.dataScript = script;
		}

		private void AddDropDataScript(IEnumerable script)
		{
			this.dropDataScript = script;
		}

		private void AddPermissionScript(IEnumerable script)
		{
			this.permissionScript.AddRange(ScriptObjectContainer.GetStringArray(script));
		}

		protected virtual void ValidateSource(Urn source)
		{
			if (source != this.urn)
			{
				throw new InvalidOperationException();
			}
		}

		protected static string[] GetStringArray(IEnumerable script)
		{
			if (script == null)
			{
				throw new ArgumentNullException("script");
			}
			StringCollection stringCollection = new StringCollection();
			int num = 0;
			foreach (object current in script)
			{
				stringCollection.Add((string)current);
				num++;
			}
			string[] array = new string[num];
			stringCollection.CopyTo(array, 0);
			return array;
		}
	}
}
